/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 *
 * http://www.gnu.org/copyleft/gpl.html
 */

package l1j.server.server.model.Instance;

import java.util.Arrays;
import java.util.List;
import java.util.Timer;

import l1j.opqlo.NewSystem.Attack.L1AttackModel;
import l1j.opqlo.NewSystem.Attack.L1AttackPc;
import l1j.opqlo.Server.L1World.L1World;
import l1j.server.server.ActionCodes;
import l1j.server.server.IdFactory;
import l1j.server.server.datatables.ExpTable;
import l1j.server.server.datatables.PetItemTable;
import l1j.server.server.datatables.PetTable;
import l1j.server.server.datatables.PetTypeTable;
import l1j.server.server.model.L1CastleLocation;
import l1j.server.server.model.L1Character;
import l1j.server.server.model.L1Inventory;
import l1j.server.server.model.L1PetFood;
import l1j.server.server.serverpackets.S_DoActionGFX;
import l1j.server.server.serverpackets.S_HPMeter;
import l1j.server.server.serverpackets.S_NpcChatPacket;
import l1j.server.server.serverpackets.S_PetCtrlMenu;
import l1j.server.server.serverpackets.S_PetMenuPacket;
import l1j.server.server.serverpackets.S_PetPack;
import l1j.server.server.serverpackets.S_ServerMessage;
import l1j.server.server.serverpackets.S_SummonPack;
import l1j.server.server.templates.L1Npc;
import l1j.server.server.templates.L1Pet;
import l1j.server.server.templates.L1PetItem;
import l1j.server.server.templates.L1PetType;
import l1j.server.server.utils.Random;
import static l1j.server.server.model.skill.L1SkillId.*;
import l1j.server.server.serverpackets.S_SkillHaste;//TODO 寵物加速效果阿傑
import l1j.server.server.serverpackets.S_SkillSound;//TODO 寵物進化效果 阿傑
public class L1PetInstance extends L1NpcInstance {

	private static final long serialVersionUID = 1L;

	// ターゲットがいない場合の処理
	@Override
	public boolean noTarget() {
		if (_currentPetStatus == 3) { // ● 休憩の場合
			return true;
		
		} else if (_currentPetStatus == 4) { // ● 配備の場合
			if ((_petMaster != null)
					&& (_petMaster.getMapId() == getMapId())
					&& (getLocation().getTileLineDistance(_petMaster.getLocation()) < 5)) {
				if (_npcMove != null) {
					int dir = _npcMove.targetReverseDirection(_petMaster.getX(), _petMaster.getY());
					dir = _npcMove.checkObject(dir);
					_npcMove.setDirectionMove(dir);
					setSleepTime(calcSleepTime(getPassispeed(), MOVE_SPEED));
				}

			} else { // 主人を見失うか５マス以上はなれたら休憩状態に
				_currentPetStatus = 3;
				return true;
			}
		} else if (_currentPetStatus == 5) { // ● 警戒の場合はホームへ
			if (Math.abs(getHomeX() - getX()) > 1
					|| Math.abs(getHomeY() - getY()) > 1) {
				if (_npcMove != null) {
					final int dir = _npcMove.moveDirection(getHomeX(), getHomeY());
					if (dir == -1) { // ホームが離れすぎてたら現在地がホーム
						setHomeX(getX());
						setHomeY(getY());
					} else {
						_npcMove.setDirectionMove(dir);
						setSleepTime(calcSleepTime(getPassispeed(), MOVE_SPEED));
					}
				}
			}
		} else if (_currentPetStatus == 7) { // ● ペットの笛で主人の元へ
			if ((this._petMaster != null)
					&& (this._petMaster.getMapId() == this.getMapId())
					&& (this.getLocation().getTileLineDistance(
							this._petMaster.getLocation()) <= 1)) {
				this._currentPetStatus = 3;
				return true;
			}
			if (_npcMove != null) {
				final int locx = _petMaster.getX() +Random.nextInt(1);
				final int locy = _petMaster.getY() + Random.nextInt(1);
				final int dirx = _npcMove.moveDirection(locx, locy);
				if (dirx == -1) { // 主人を見失うかはなれたらその場で休憩状態に
					_currentPetStatus = 3;
					return true;
				}
				_npcMove.setDirectionMove(dirx);
				setSleepTime(calcSleepTime(getPassispeed(), MOVE_SPEED));
			}
		} else if (_petMaster != null && _petMaster.getMapId() == getMapId()) { // ●
			// 主人を追尾
			if (getLocation().getTileLineDistance(_petMaster.getLocation()) > 2) {
				if (_npcMove != null) {
					final int dir = _npcMove.moveDirection(_petMaster.getX(), _petMaster.getY());
					_npcMove.setDirectionMove(dir);
					setSleepTime(calcSleepTime(getPassispeed(), MOVE_SPEED));
				}
			}
		} 
		return false;
	}

	// ペットを引き出した場合
	public L1PetInstance(final L1Npc template, final L1PcInstance master, final L1Pet l1pet) {
		super(template);

		_petMaster = master;
		_itemObjId = l1pet.get_itemobjid();
		_type = PetTypeTable.getInstance().get(template.get_npcId());

		// ステータスを上書き
		setId(l1pet.get_objid());
		setName(l1pet.get_name());
		setLevel(l1pet.get_level());
		// HPMPはMAXとする
		setMaxHp(l1pet.get_hp());
		setCurrentHpDirect(l1pet.get_hp());
		setMaxMp(l1pet.get_mp());
		setCurrentMpDirect(l1pet.get_mp());
		setExp(l1pet.get_exp());
		setExpPercent(ExpTable.getExpPercentage(l1pet.get_level(), l1pet.get_exp()));
		setLawful(l1pet.get_lawful());
		setTempLawful(l1pet.get_lawful());
		setMaster(master);
		int x =master.getX() + Random.nextInt(5) - 2;
		int y =master.getY() + Random.nextInt(5) - 2;
		final short mapId = master.getMapId();
		if(L1CastleLocation.checkInAllfatArea(x, y,mapId)){//opqlo 賭肥區判斷
			x =master.getX();
			y =master.getY();
		}
		setX(x);
		setY(y);
		setMap(mapId);
		setHeading(5);
		setLightSize(template.getLightSize());

		_currentPetStatus = 3;

		L1World.getInstance().storeObject(this);
		L1World.getInstance().addVisibleObject(this);
		for (final L1PcInstance pc : L1World.getInstance().getRecognizePlayer(this)) {
			onPerceive(pc);
		}
		//TODO 寵物領出後獲得加速術1800秒 by 阿傑
		broadcastPacketX8(new S_SkillSound(getId(), 3104));
		broadcastPacketX8(new S_SkillHaste(getId(), 1, 0));
		setMoveSpeed(1);
		setSkillEffect(43, 1800000);
		//TODO 寵物領出後獲得加速術1800秒 by 阿傑
		master.addPet(this);
	}

	// ペットをテイムした場合
	public L1PetInstance(final L1NpcInstance target, final L1PcInstance master, final int itemid) {
		super(null);

		_petMaster = master;
		_itemObjId = itemid;
		_type = PetTypeTable.getInstance().get(
				target.getNpcTemplate().get_npcId());

		// ステータスを上書き
		setId(IdFactory.getInstance().nextId());
		setting_template(target.getNpcTemplate());
		setCurrentHpDirect(target.getCurrentHp());
		setCurrentMpDirect(target.getCurrentMp());
		setExp(750); // Lv.5のEXP
		setExpPercent(0);
		setLawful(0);
		setTempLawful(0);

		setMaster(master);
		setX(target.getX());
		setY(target.getY());
		setMap(target.getMapId());
		setHeading(target.getHeading());
		setLightSize(target.getLightSize());
		setPetcost(6);
		setInventory(target.getInventory());
		target.setInventory(null);

		_currentPetStatus = 3;
		//TODO 寵物馴服後不回血回魔修正 by 阿傑
		stopHpRegeneration();
		if (getMaxHp() > getCurrentHp()) {
			startHpRegeneration();
		}
		stopMpRegeneration();
		if (getMaxMp() > getCurrentMp()) {
			startMpRegeneration();
		}
		//TODO 寵物馴服後不回血回魔修正 by 阿傑
		target.deleteMe();
		L1World.getInstance().storeObject(this);
		L1World.getInstance().addVisibleObject(this);
		for (final L1PcInstance pc : L1World.getInstance().getRecognizePlayer(this)) {
			onPerceive(pc);
		}

		master.addPet(this);
		PetTable.getInstance().storeNewPet(target, getId(), itemid);
	}

	// 攻撃でＨＰを減らすときはここを使用
	@Override
	public void receiveDamage(final L1Character attacker, int damage) {
		if (getCurrentHp() > 0) {
			if (damage > 0) { // 回復の場合は攻撃しない。
				setHate(attacker, 0); // ペットはヘイト無し
				removeSkillEffect(FOG_OF_SLEEPING);
			}

			if (attacker instanceof L1PcInstance && damage > 0) {
				((L1PcInstance) attacker).setPetTarget(this);
			}

			//TODO 目標在安區、攻擊者在安區、NOPVP
			if (attacker instanceof L1PetInstance) {
				final L1PetInstance pet = (L1PetInstance) attacker;
				if ((getZoneType() == 1) || (pet.getZoneType() == 1)) {
					damage = 0;
				}
			} else if (attacker instanceof L1SummonInstance) {
				if ((getZoneType() == 1) || (((L1SummonInstance) attacker).getZoneType() == 1)) {
					damage = 0;
				}
			}
			//TODO 目標在安區、攻擊者在安區、NOPVP

			final int newHp = getCurrentHp() - damage;
			if (newHp <= 0) {
				death(attacker);
			} else {
				setCurrentHp(newHp);
			}
		} else if (!isDead()) { // 念のため
			death(attacker);
		}
	}

	public synchronized void death(final L1Character lastAttacker) {
		if (!isDead()) {
			setDead(true);
			setStatus(ActionCodes.ACTION_Die);
			setCurrentHp(0);
			getMap().setPassable(getLocation(), true);
			broadcastPacketAll(new S_DoActionGFX(getId(), ActionCodes.ACTION_Die));
		}
	}

	public void evolvePet(final int new_itemobjid) {

		final L1Pet l1pet = PetTable.getInstance().getTemplate(_itemObjId);
		if (l1pet == null) {
			return;
		}

		final int newNpcId = _type.getNpcIdForEvolving();
		// 進化前のmaxHp,maxMpを退避
		final int tmpMaxHp = getMaxHp();
		final int tmpMaxMp = getMaxMp();

		transform(newNpcId);
		_type = PetTypeTable.getInstance().get(newNpcId);
		//寵物進化時的效果 by 阿傑
		broadcastPacketX8(new S_SkillSound(getId(), 2127));
		//寵物進化時的效果 by 阿傑
		setLevel(1);
		// HPMPを元の半分にする
		setMaxHp(tmpMaxHp / 2);
		setMaxMp(tmpMaxMp / 2);
		setCurrentHpDirect(getMaxHp());
		setCurrentMpDirect(getMaxMp());
		setExp(0);
		setExpPercent(0);

		// インベントリを空にする
		getInventory().clearItems();

		// 古いペットをDBから消す
		PetTable.getInstance().deletePet(_itemObjId);

		// 新しいペットをDBに書き込む
		l1pet.set_itemobjid(new_itemobjid);
		l1pet.set_npcid(newNpcId);
		l1pet.set_name(getName());
		l1pet.set_level(getLevel());
		l1pet.set_hp(getMaxHp());
		l1pet.set_mp(getMaxMp());
		l1pet.set_exp(getExp());
		PetTable.getInstance().storeNewPet(this, getId(), new_itemobjid);

		_itemObjId = new_itemobjid;
	}

	// 解放処理
	public void liberate() {
		final L1MonsterInstance monster = new L1MonsterInstance(getNpcTemplate());
		monster.setId(IdFactory.getInstance().nextId());

		monster.setX(getX());
		monster.setY(getY());
		monster.setMap(getMapId());
		monster.setHeading(getHeading());
		monster.set_storeDroped(true);
		monster.setInventory(getInventory());
		setInventory(null);
		monster.setLevel(getLevel());
		monster.setMaxHp(getMaxHp());
		monster.setCurrentHpDirect(getCurrentHp());
		monster.setMaxMp(getMaxMp());
		monster.setCurrentMpDirect(getCurrentMp());

		_petMaster.getPetList().remove(getId());
		//TODO 關閉寵物控制圖形介面 by99團隊
		if (_petMaster.getPetList().isEmpty()) {
			//TODO 3.5C寵物圖型介面UI變更 
			_petMaster.sendPackets(new S_PetCtrlMenu(_master, monster, false));
			//TODO 3.5C寵物圖型介面UI變更 
		}
		//TODO 關閉寵物控制圖形介面 by99團隊
		deleteMe();
		setDead(true);//opqlo 
		// DBとPetTableから削除し、ペットアミュも破棄
		_petMaster.getInventory().removeItem(_itemObjId, 1);
		PetTable.getInstance().deletePet(_itemObjId);

		L1World.getInstance().storeObject(monster);
		L1World.getInstance().addVisibleObject(monster);
		for (final L1PcInstance pc : L1World.getInstance().getRecognizePlayer(monster)) {
			onPerceive(pc);
		}
	}

	// ペットの持ち物を収集
	public void collect() {
		L1Inventory targetInventory = _petMaster.getInventory();
		final List<L1ItemInstance> items = _inventory.getItems();
		final int size = _inventory.getSize();
		for (int i = 0; i < size; i++) {
			final L1ItemInstance item = items.get(0);
			if (item.isEquipped()) { // 装備中のペットアイテム
				continue;
			}
			if (_petMaster.getInventory().checkAddItem( // 容量重量確認及びメッセージ送信
					item, item.getCount()) == L1Inventory.OK) {
				_inventory.tradeItem(item, item.getCount(), targetInventory);
				_petMaster.sendPackets(new S_ServerMessage(143, getName(), item
						.getLogName())); // \f1%0が%1をくれました。
			} else { // 持てないので足元に落とす
				targetInventory = L1World.getInstance().getInventory(getX(),
						getY(), getMapId());
				_inventory.tradeItem(item, item.getCount(), targetInventory);
			}
		}
	}

	// リスタート時にDROPを地面に落とす
	public void dropItem() {
		final L1Inventory targetInventory = L1World.getInstance().getInventory(
				getX(), getY(), getMapId());
		final List<L1ItemInstance> items = _inventory.getItems();
		final int size = _inventory.getSize();
//		while(!_inventory.isEmpty()){
		for (int i = 0; i < size; i++) {
			final L1ItemInstance item = items.get(0);
			item.setEquipped(false);
			_inventory.tradeItem(item, item.getCount(), targetInventory);
		}
	}

	// ペットの笛を使った
	public void call() {
		final int id = _type.getMessageId(L1PetType.getMessageNumber(getLevel()));
		if (id != 0) {
			broadcastPacketAll(new S_NpcChatPacket(this, "$" + id, 0));
		}

		setCurrentPetStatus(7); // 主人の近くで休憩状態
	}

	public void setTarget(final L1Character target) {
		if (target != null
				&& (_currentPetStatus == 1 || _currentPetStatus == 2 || _currentPetStatus == 5)) {
			setHate(target, 0);
			if (!isAiRunning()) {
				startAI();
			}
		}
	}

	public void setMasterTarget(final L1Character target) {
		if (target != null
				&& (_currentPetStatus == 1 || _currentPetStatus == 5)) {
			setHate(target, 0);
			if (!isAiRunning()) {
				startAI();
			}
		}
	}

	@Override
	public void onPerceive(final L1PcInstance perceivedFrom) {
		perceivedFrom.addKnownObject(this);
		perceivedFrom.sendPackets(new S_PetPack(this, perceivedFrom)); // ペット系オブジェクト認識
		if (isDead()) {
			perceivedFrom.sendPackets(new S_DoActionGFX(getId(),ActionCodes.ACTION_Die));
		}
		 if (perceivedFrom.hasSkillEffect(GMSTATUS_HPBAR)) { 
			 perceivedFrom.sendPackets(new S_HPMeter(this)); 
			} 
	}

	@Override
	public void onAction(final L1PcInstance player) {
	//	final L1Character cha = this.getMaster();
		final L1PcInstance master = (L1PcInstance) _master;
		if (master.isTeleport()) { // テレポート処理中
			return;
		}
		if (getZoneType() == 1) { // 攻撃される側がセーフティーゾーン
			final L1AttackModel attack_mortion = new L1AttackPc(player, this);
			attack_mortion.action();
			return;
		}

		if (player.checkNonPvP(player, this)) {
			return;
		}
		final L1AttackModel attack = new L1AttackPc(player, this);
		if (attack.calcHit()) {
			attack.calcDamage();
		}
		attack.action();
		attack.commit();
	}

	@Override
	public void onTalkAction(final L1PcInstance player) {
		if (isDead()) {
			return;
		}
		if (_petMaster.equals(player)) {
			player.sendPackets(new S_PetMenuPacket(this, getExpPercent()));
			final L1Pet l1pet = PetTable.getInstance().getTemplate(_itemObjId);
			// XXX ペットに話しかけるたびにDBに書き込む必要はない
			if (l1pet != null) {
				l1pet.set_exp(getExp());
				l1pet.set_level(getLevel());
				l1pet.set_hp(getMaxHp());
				l1pet.set_mp(getMaxMp());
				PetTable.getInstance().storePet(l1pet); // DBに書き込み
			}
		}
	}

	@Override
	public void onFinalAction(final L1PcInstance player, final String action) {
		final int status = actionType(action);
		if (status == 0) {
			return;
		}
		if (status == 6) {
			//TODO 3.5C關閉寵物圖型介面UI變更by99團隊
			final L1PcInstance _petMaster = (L1PcInstance) _master;
			liberate(); // ペットの解放
			final Object[] petList = _petMaster.getPetList().values().toArray();
			for (final Object petObject : petList) {
				if (petObject instanceof L1SummonInstance) {
					_petMaster.sendPackets(new S_SummonPack(((L1SummonInstance) petObject), _petMaster));
					return;
				} else if (petObject instanceof L1PetInstance) {
					_petMaster.sendPackets(new S_PetPack(((L1PetInstance) petObject), _petMaster));
					return;
				}
			}
			//TODO 3.5C關閉寵物圖型介面UI變更by99團隊
		} else {
			// 同じ主人のペットの状態をすべて更新
			final Object[] petList = _petMaster.getPetList().values().toArray();
			for (final Object petObject : petList) {
				if (petObject instanceof L1PetInstance) { // ペット
					final L1PetInstance pet = (L1PetInstance) petObject;
					//opqlo 解除主人等級比寵物等級低的時候不能控制。
					//if (_petMaster != null && _petMaster.getLevel() >= pet.getLevel()) {
					if (_petMaster != null){
						pet.setCurrentPetStatus(status);
					} else {
						final L1PetType type = PetTypeTable.getInstance().get(pet.getNpcTemplate().get_npcId());
						final int id = type.getDefyMessageId();
						if (id != 0) {broadcastPacketAll(new S_NpcChatPacket(pet,"$" + id, 0));
						}
					}
				}
			}
		}
	}

	@Override
	public void onItemUse() {
		/*刪除
		 * if (!isActived()) { useItem(USEITEM_HASTE, 100);
		 * １００％の確率でヘイストポーション使用 }
		 刪除*/
		// TODO 喝綠判斷變更 by 阿傑
		if (!hasSkillEffect(1001) && !hasSkillEffect(43)) {//TODO 補上加速術判斷
			useItem(USEITEM_HASTE, 100); // １００％の確率でヘイストポーション使用
		}
		// TODO 喝綠判斷變更 by 阿傑
		if (getCurrentHp() * 100 / getMaxHp() < 40) { // ＨＰが４０％きったら
			useItem(USEITEM_HEAL, 100); // １００％の確率で回復ポーション使用
		}
	}

	@Override
	public void onGetItem(final L1ItemInstance item) {
		if (getNpcTemplate().get_digestitem() > 0) {
			setDigestItem(item);
		}
		Arrays.sort(healPotions);
		Arrays.sort(haestPotions);
		if (Arrays.binarySearch(healPotions, item.getItem().getItemId()) >= 0) {
			if (getCurrentHp() != getMaxHp()) {
				useItem(USEITEM_HEAL, 100);
			}
		} else if (Arrays
				.binarySearch(haestPotions, item.getItem().getItemId()) >= 0) {
			useItem(USEITEM_HASTE, 100);
		}
	}

	private int actionType(final String action) {
		int status = 0;
		if (action.equalsIgnoreCase("aggressive")) { // 攻撃態勢
			status = 1;
		} else if (action.equalsIgnoreCase("defensive")) { // 防御態勢
			status = 2;
		} else if (action.equalsIgnoreCase("stay")) { // 休憩
			status = 3;
		} else if (action.equalsIgnoreCase("extend")) { // 配備
			status = 4;
		} else if (action.equalsIgnoreCase("alert")) { // 警戒
			status = 5;
		} else if (action.equalsIgnoreCase("dismiss")) { // 解散
			status = 6;
		} else if (action.equalsIgnoreCase("getitem")) { // 収集
			collect();
		}
		return status;
	}

	@Override
	public void setCurrentHp(final int i) {
		int currentHp = i;
		if (currentHp >= getMaxHp()) {
			currentHp = getMaxHp();
		}
		setCurrentHpDirect(currentHp);

		if (getMaxHp() > getCurrentHp()) {
			startHpRegeneration();
		}

		if (_petMaster != null) {
			final int HpRatio = 100 * currentHp / getMaxHp();
			final L1PcInstance Master = _petMaster;
			Master.sendPackets(new S_HPMeter(getId(), HpRatio));
		}
	}

	@Override
	public void setCurrentMp(final int i) {
		int currentMp = i;
		if (currentMp >= getMaxMp()) {
			currentMp = getMaxMp();
		}
		setCurrentMpDirect(currentMp);

		if (getMaxMp() > getCurrentMp()) {
			startMpRegeneration();
		}
	}

	public void setCurrentPetStatus(final int i) {
		_currentPetStatus = i;
		if (_currentPetStatus == 5) {
			setHomeX(getX());
			setHomeY(getY());
		}
		if (_currentPetStatus == 7) {
			allTargetClear();
		}

		if (_currentPetStatus == 3) {
			allTargetClear();
		} else {
			if (!isAiRunning()) {
				startAI();
			}
		}
	}

	public int getCurrentPetStatus() {
		return _currentPetStatus;
	}

	public int getItemObjId() {
		return _itemObjId;
	}

	public void setExpPercent(final int expPercent) {
		_expPercent = expPercent;
	}

	public int getExpPercent() {
		return _expPercent;
	}

	private L1ItemInstance _weapon;

	public void setWeapon(final L1ItemInstance weapon) {
		_weapon = weapon;
	}

	public L1ItemInstance getWeapon() {
		return _weapon;
	}

	private L1ItemInstance _armor;

	public void setArmor(final L1ItemInstance armor) {
		_armor = armor;
	}

	public L1ItemInstance getArmor() {
		return _armor;
	}

	private int _hitByWeapon;

	public void setHitByWeapon(final int i) {
		_hitByWeapon = i;
	}

	public int getHitByWeapon() {
		return _hitByWeapon;
	}

	private int _damageByWeapon;

	public void setDamageByWeapon(final int i) {
		_damageByWeapon = i;
	}

	public int getDamageByWeapon() {
		return _damageByWeapon;
	}

	private int _currentPetStatus;
	private final L1PcInstance _petMaster;
	private int _itemObjId;
	private L1PetType _type;
	private int _expPercent;

	public L1PetType getPetType() {
		return _type;
	}
	// 寵物飽食度計時器
	private L1PetFood _petFood;

	public void startFoodTimer(L1PetInstance pet) {
		_petFood = new L1PetFood(pet, _itemObjId);
		new Timer(true).scheduleAtFixedRate(_petFood, 1000, 200000); // 每 X秒減少
	}

	public void stopFoodTimer(L1PetInstance pet) {
		if (_petFood != null) {
			_petFood.cancel();
			_petFood = null;
		}
	}
	// 使用寵物裝備
	public void usePetWeapon(L1PetInstance pet, L1ItemInstance weapon) {
		if (pet.getWeapon() == null) {
			setPetWeapon(pet, weapon);
		}
		else { // 既に何かを装備している場合、前の装備をはずす
			if (pet.getWeapon().equals(weapon)) {
				removePetWeapon(pet, pet.getWeapon());
			}
			else {
				removePetWeapon(pet, pet.getWeapon());
				setPetWeapon(pet, weapon);
			}
		}
	}

	public void usePetArmor(L1PetInstance pet, L1ItemInstance armor) {
		if (pet.getArmor() == null) {
			setPetArmor(pet, armor);
		}
		else { // 既に何かを装備している場合、前の装備をはずす
			if (pet.getArmor().equals(armor)) {
				removePetArmor(pet, pet.getArmor());
			}
			else {
				removePetArmor(pet, pet.getArmor());
				setPetArmor(pet, armor);
			}
		}
	}
	private void setPetWeapon(L1PetInstance pet, L1ItemInstance weapon) {
		int itemId = weapon.getItem().getItemId();
		L1PetItem petItem = PetItemTable.getInstance().getTemplate(itemId);
		if (petItem == null) {
			return;
		}

		pet.setHitByWeapon(petItem.getHitModifier());
		pet.setDamageByWeapon(petItem.getDamageModifier());
		pet.addStr(petItem.getAddStr());
		pet.addCon(petItem.getAddCon());
		pet.addDex(petItem.getAddDex());
		pet.addInt(petItem.getAddInt());
		pet.addWis(petItem.getAddWis());
		pet.addMaxHp(petItem.getAddHp());
		pet.addMaxMp(petItem.getAddMp());
		pet.addSp(petItem.getAddSp());
		pet.addMr(petItem.getAddMr());

		pet.setWeapon(weapon);
		weapon.setEquipped(true);
	}

	private void removePetWeapon(L1PetInstance pet, L1ItemInstance weapon) {
		int itemId = weapon.getItem().getItemId();
		L1PetItem petItem = PetItemTable.getInstance().getTemplate(itemId);
		if (petItem == null) {
			return;
		}

		pet.setHitByWeapon(0);
		pet.setDamageByWeapon(0);
		pet.addStr(-petItem.getAddStr());
		pet.addCon(-petItem.getAddCon());
		pet.addDex(-petItem.getAddDex());
		pet.addInt(-petItem.getAddInt());
		pet.addWis(-petItem.getAddWis());
		pet.addMaxHp(-petItem.getAddHp());
		pet.addMaxMp(-petItem.getAddMp());
		pet.addSp(-petItem.getAddSp());
		pet.addMr(-petItem.getAddMr());

		pet.setWeapon(null);
		weapon.setEquipped(false);
	}

	private void setPetArmor(L1PetInstance pet, L1ItemInstance armor) {
		int itemId = armor.getItem().getItemId();
		L1PetItem petItem = PetItemTable.getInstance().getTemplate(itemId);
		if (petItem == null) {
			return;
		}

		pet.addAc(petItem.getAddAc());
		pet.addStr(petItem.getAddStr());
		pet.addCon(petItem.getAddCon());
		pet.addDex(petItem.getAddDex());
		pet.addInt(petItem.getAddInt());
		pet.addWis(petItem.getAddWis());
		pet.addMaxHp(petItem.getAddHp());
		pet.addMaxMp(petItem.getAddMp());
		pet.addSp(petItem.getAddSp());
		pet.addMr(petItem.getAddMr());

		pet.setArmor(armor);
		armor.setEquipped(true);
	}

	private void removePetArmor(L1PetInstance pet, L1ItemInstance armor) {
		int itemId = armor.getItem().getItemId();
		L1PetItem petItem = PetItemTable.getInstance().getTemplate(itemId);
		if (petItem == null) {
			return;
		}

		pet.addAc(-petItem.getAddAc());
		pet.addStr(-petItem.getAddStr());
		pet.addCon(-petItem.getAddCon());
		pet.addDex(-petItem.getAddDex());
		pet.addInt(-petItem.getAddInt());
		pet.addWis(-petItem.getAddWis());
		pet.addMaxHp(-petItem.getAddHp());
		pet.addMaxMp(-petItem.getAddMp());
		pet.addSp(-petItem.getAddSp());
		pet.addMr(-petItem.getAddMr());

		pet.setArmor(null);
		armor.setEquipped(false);
	}

}
